package com.yami.shop.bean.param.hnaPay;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.yami.shop.common.util.DateUtils;
import lombok.Data;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 交易报文
 * 交易报文是面向商户的，各交易报文中的字段必须与商户提交请求中的参数key一致
 * <p>Title: BaseTransForm</p>
 * <p>Description: </p>
 * <p>Company: </p>
 */
@Data
public abstract class BaseTransForm implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final String VERSION = "version";
    public static final String TRAN_CODE = "tranCode";
    public static final String MER_ID = "merId";
    public static final String MER_ORDER_ID = "merOrderId";
    public static final String CHARSET = "charset";
    public static final String SIGN_TYPE = "signType";
    public static final String SIGN_VALUE = "signValue";
    public static final String MER_ATTACH = "merAttach";
    public static final String SUBMIT_TIME = "submitTime";
    public static final String CERT_INFO = "certInfo";
    public static final String MSG_CIPHER_TEXT = "msgCiphertext";
    public static final String RESULT_CODE = "resultCode";
    public static final String ERROR_CODE = "errorCode";
    public static final String ERROR_MSG = "errorMsg";

    // 暂定公共的报文字段
    protected String tranCode;
    protected String version;
    protected String merId;
    protected String merOrderId;
    protected String signType;
    protected String signValue;
    protected String msgCiphertext;
    protected String charset;
    protected String merAttach;
    protected String submitTime;

    // 提交地址
    protected String submitUrl;
    //证件资料信息
    protected String certInfo;

    /**
     * 获取公共返回参数<br>
     * Map中的key必须与返回XML文件中的field的name值一致<br>
     * 子类可选择性重写
     *
     * @return
     */
    @SuppressWarnings("static-access")
    public Map<String, Object> getCommonRespParams() {
        Map<String, Object> commonParams = new HashMap<String, Object>();
        commonParams.put(this.VERSION, this.version);
        commonParams.put(this.TRAN_CODE, this.tranCode);
        commonParams.put(this.MER_ORDER_ID, this.merOrderId);
        commonParams.put(this.MER_ID, this.merId);
        commonParams.put(this.MER_ATTACH, this.merAttach);
        commonParams.put(this.CHARSET, this.charset);
        commonParams.put(this.SIGN_TYPE, this.signType);
        return commonParams;
    }

    /**
     * 获取共用请求的签名字段
     *
     * @return Map<String, Object>
     * @author wgy
     * @date 2018年8月10日 上午10:26:54
     * @description 一句话描述功能
     */
    @SuppressWarnings("static-access")
    public Map<String, Object> getCommonReqSignParams() {
        Map<String, Object> commonParams = new HashMap<String, Object>();
        commonParams.put(this.TRAN_CODE, this.tranCode);
        commonParams.put(this.VERSION, this.version);
        commonParams.put(this.MER_ID, this.merId);
        commonParams.put(this.MER_ORDER_ID, this.merOrderId);
        commonParams.put(this.SUBMIT_TIME, this.submitTime);
        commonParams.put(this.MSG_CIPHER_TEXT, this.msgCiphertext);
        commonParams.put(this.SIGN_TYPE, this.signType);
        if(ObjectUtil.isNotNull(this.certInfo)){
            commonParams.put(this.CERT_INFO, this.certInfo);
        }
        return commonParams;
    }

    /**
     * 获取加密json串明文
     *
     * @return String
     * @author wgy
     * @date 2018年8月27日 下午6:08:46
     * @description 一句话描述功能
     */
    public abstract String getEncryptJsonStr();

    /**
     * 获取验签字段
     *
     * @return
     */
    public abstract String getVerifyJsonStr();

    /**
     * 获取提交字段
     *
     * @return
     */
    public abstract String getSubmitJsonStr();


    public void initCommonParams(String tranCode, String merId, String payNo) {
        this.version = "1.0";
        this.tranCode = tranCode;
        this.merId = merId;
        this.merOrderId = ObjectUtil.isNotNull(payNo) ? payNo + RandomUtil.randomNumbers(2) : tranCode+"_"+ DateUtils.dateToStrYmdHmsXs(new Date());
        this.submitTime = DateUtils.dateToStrYmdHmsXs(new Date());
        this.signType = "1";
        this.merAttach = "";
        this.charset = "UTF-8";
    }

    public String getCommonSignStr() {
        StringBuffer sb = new StringBuffer();
        sb.append(this.VERSION);
        sb.append("=[");
        sb.append(getVersion());
        sb.append("]");

        sb.append(this.TRAN_CODE);
        sb.append("=[");
        sb.append(getTranCode());
        sb.append("]");

        sb.append(this.MER_ID);
        sb.append("=[");
        sb.append(getMerId());
        sb.append("]");

        sb.append(this.MER_ORDER_ID);
        sb.append("=[");
        sb.append(getMerOrderId());
        sb.append("]");

        sb.append(this.SUBMIT_TIME);
        sb.append("=[");
        sb.append(getSubmitTime());
        sb.append("]");

        sb.append(this.MSG_CIPHER_TEXT);
        sb.append("=[");
        sb.append(getMsgCiphertext());
        sb.append("]");

        sb.append(this.SIGN_TYPE);
        sb.append("=[");
        sb.append(getSignType());
        sb.append("]");

        return sb.toString();
    }

    public String getValueByReflet(Object model, String paraName) {
        // 返回值
        String value = "";
        try {
            // 获取属性值
            Field[] fields = model.getClass().getDeclaredFields();

            for (Field field : fields) {
                field.setAccessible(true);

                if (field.getName().equals(paraName)) {
                    value = (String) field.get(model);

                    break;
                }
            }
        } catch (Exception e) {

        }
        return value;
    }

    public String getJsonStr(Object model, String[] strArr) {
        JSONObject json = new JSONObject(true);
        for (String file : strArr) {
            json.put(file, getValueByReflet(model, file));
        }
        return json.toJSONString();
    }


    public static String getVerifyDataByTranCode(String tranCode, Map<String, Object> responseMap) {

        StringBuffer sb = new StringBuffer();

        String[] verifyFields = getVerifyArrByTranCode(tranCode);

        for (int i = 0; i < verifyFields.length; i++) {
            sb.append(verifyFields[i]);
            sb.append("=[");
            sb.append(responseMap.get(verifyFields[i]) == null ? "" : responseMap.get(verifyFields[i]));
            sb.append("]");
        }

        return sb.toString();

    }

    private static String[] getVerifyArrByTranCode(String tranCode) {
        switch (tranCode) {
            case "Q001":
                return Q001TransForm.verifyArr;
            case "Q002":
                return Q002TransForm.verifyArr;
            case "Q004":
                return Q004TransForm.verifyArr;
            case "R001":
                return R001TransForm.verifyArr;
            case "R002":
                return R002TransForm.verifyArr;
            case "R003":
                return R003TransForm.verifyArr;
            case "R007":
                return R007TransForm.verifyArr;
            case "R008":
                return R008TransForm.verifyArr;
            case "R009":
                return R009TransForm.verifyArr;
            case "R010":
                return R010TransForm.verifyArr;
            case "R011":
                return R011TransForm.verifyArr;
            case "T002":
                return T002TransForm.verifyArr;
            case "T003":
                return T003TransForm.verifyArr;
            case "T005":
                return T005TransForm.verifyArr;
            case "T006":
                return T006TransForm.verifyArr;
            case "T007":
                return T007TransForm.verifyArr;
            case "T008":
                return T008TransForm.verifyArr;
            case "T013":
                return T013TransForm.verifyArr;
            case "F001":
                return F001TransForm.verifyArr;
            default:
                return null;
        }
    }

}
